home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / hplip / check.py < prev    next >
Text File  |  2008-10-13  |  29KB  |  803 lines

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19. #
  20. # Author: Don Welch
  21. #
  22.  
  23. __version__ = '14.0'
  24. __title__ = 'Dependency/Version Check Utility'
  25. __doc__ = "Check the existence and versions of HPLIP dependencies."
  26.  
  27. # Std Lib
  28. import sys
  29. import os
  30. import getopt
  31. import commands
  32. import re
  33.  
  34. # Local
  35. from base.g import *
  36. from base import utils, tui, models
  37. from installer import dcheck
  38. from installer.core_install import *
  39.  
  40. device_avail = False
  41. try:
  42.     from base import device, pml
  43. except ImportError:
  44.     log.debug("Device library is not avail.")
  45. else:
  46.     device_avail = True
  47.  
  48.  
  49. USAGE = [(__doc__, "", "name", True),
  50.          ("Usage: hp-check/check.py [OPTIONS]", "", "summary", True),
  51.          utils.USAGE_OPTIONS,
  52.          ("Compile-time check:", "-c or --compile", "option", False),
  53.          ("Run-time check:", "-r or --run", "option", False),
  54.          ("Compile and run-time checks:", "-b or --both (default)", "option", False),
  55.          utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
  56.          utils.USAGE_LOGGING_PLAIN,
  57.          utils.USAGE_HELP,
  58.          utils.USAGE_NOTES,
  59.          ("1. For checking for the proper build environment for the HPLIP supplied tarball (.tar.gz or .run),", "", "note", False), 
  60.          ("use the --compile or --both switches.", "", "note", False),
  61.          ("2. For checking for the proper runtime environment for a distro supplied package (.deb, .rpm, etc),", "", "note", False), 
  62.          ("use the --runtime switch.", "", "note", False),
  63.         ]
  64.  
  65. def usage(typ='text'):
  66.     if typ == 'text':
  67.         utils.log_title(__title__, __version__)
  68.  
  69.     utils.format_text(USAGE, typ, __title__, 'hp-check', __version__)
  70.     sys.exit(0)        
  71.  
  72.  
  73. build_str = "HPLIP will not build, install, and/or function properly without this dependency."
  74.  
  75. pat_deviceuri = re.compile(r"""(.*):/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*)|ip=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[^&]*))(?:&port=(\d))?""", re.I)
  76.  
  77. pat_cups_error_log = re.compile("""^loglevel\s?(debug|debug2|warn|info|error|none)""", re.I)
  78.  
  79.  
  80. def parseDeviceURI(device_uri):
  81.     m = pat_deviceuri.match(device_uri)
  82.  
  83.     if m is None:
  84.         raise Error(ERROR_INVALID_DEVICE_URI)
  85.  
  86.     back_end = m.group(1).lower() or ''
  87.     is_hp = (back_end in ('hp', 'hpfax', 'hpaio'))
  88.     bus = m.group(2).lower() or ''
  89.  
  90.     if bus not in ('usb', 'net', 'bt', 'fw', 'par'):
  91.         raise Error(ERROR_INVALID_DEVICE_URI)
  92.  
  93.     model = m.group(3) or ''
  94.     serial = m.group(4) or ''
  95.     dev_file = m.group(5) or ''
  96.     host = m.group(6) or ''
  97.     port = m.group(7) or 1
  98.  
  99.     if bus == 'net':
  100.         try:
  101.             port = int(port)
  102.         except (ValueError, TypeError):
  103.             port = 1
  104.  
  105.         if port == 0:
  106.             port = 1
  107.  
  108.     return back_end, is_hp, bus, model, serial, dev_file, host, port
  109.  
  110. num_errors = 0
  111. fmt = True
  112. overall_commands_to_run = []
  113. time_flag = DEPENDENCY_RUN_AND_COMPILE_TIME
  114.  
  115. try:
  116.     log.set_module("hp-check")
  117.  
  118.     try:
  119.         opts, args = getopt.getopt(sys.argv[1:], 'hl:gtcrb', 
  120.             ['help', 'help-rest', 'help-man', 'help-desc', 'logging=', 
  121.              'run', 'runtime', 'compile', 'both']) 
  122.  
  123.     except getopt.GetoptError, e:
  124.         log.error(e.msg)
  125.         usage()
  126.         sys.exit(1)
  127.  
  128.     if os.getenv("HPLIP_DEBUG"):
  129.         log.set_level('debug')
  130.  
  131.     log_level = 'info'
  132.  
  133.     for o, a in opts:
  134.         if o in ('-h', '--help'):
  135.             usage()
  136.  
  137.         elif o == '--help-rest':
  138.             usage('rest')
  139.  
  140.         elif o == '--help-man':
  141.             usage('man')
  142.  
  143.         elif o == '--help-desc':
  144.             print __doc__,
  145.             sys.exit(0)
  146.  
  147.         elif o in ('-l', '--logging'):
  148.             log_level = a.lower().strip()
  149.  
  150.         elif o == '-g':
  151.             log_level = 'debug'
  152.  
  153.         elif o == '-t':
  154.             fmt = False
  155.             
  156.         elif o in ('-c', '--compile'):
  157.             time_flag = DEPENDENCY_COMPILE_TIME
  158.             
  159.         elif o in ('-r', '--runtime', '--run'):
  160.             time_flag = DEPENDENCY_RUN_TIME
  161.             
  162.         elif o in ('-b', '--both'):
  163.             time_flag = DEPENDENCY_RUN_AND_COMPILE_TIME
  164.  
  165.     if not log.set_level(log_level):
  166.         usage()
  167.  
  168.     if not fmt:
  169.         log.no_formatting()
  170.  
  171.     utils.log_title(__title__, __version__)
  172.  
  173.     log.info(log.bold("Note: hp-check can be run in three modes:"))
  174.     
  175.     for l in tui.format_paragraph("1. Compile-time check mode (-c or --compile): Use this mode before compiling the HPLIP supplied tarball (.tar.gz or .run) to determine if the proper dependencies are installed to successfully compile HPLIP."):
  176.         log.info(l)
  177.         
  178.     for l in tui.format_paragraph("2. Run-time check mode (-r or --run): Use this mode to determine if a distro supplied package (.deb, .rpm, etc) or an already built HPLIP supplied tarball has the proper dependencies installed to successfully run."):
  179.         log.info(l)
  180.     
  181.     for l in tui.format_paragraph("3. Both compile- and run-time check mode (-b or --both) (Default): This mode will check both of the above cases (both compile- and run-time dependencies)."):
  182.         log.info(l)
  183.     
  184.     log.info()
  185.     
  186.     
  187.     log_file = os.path.normpath('./hp-check.log')
  188.     log.info(log.bold("Saving output in log file: %s" % log_file))
  189.     log.debug("Log file=%s" % log_file)
  190.     if os.path.exists(log_file):
  191.         os.remove(log_file)
  192.  
  193.     log.set_logfile(log_file)
  194.     log.set_where(log.LOG_TO_CONSOLE_AND_FILE)
  195.  
  196.     log.info("\nInitializing. Please wait...")
  197.     core =  CoreInstall(MODE_CHECK)
  198.     core.init()
  199.  
  200.     tui.header("SYSTEM INFO")
  201.  
  202.     log.info(log.bold("Basic system information:"))
  203.     log.info(core.sys_uname_info)
  204.  
  205.     log.info()
  206.     log.info(log.bold("Distribution:"))
  207.     log.info("%s %s" % (core.distro_name, core.distro_version))
  208.  
  209.     log.info(log.bold("\nHPOJ running?"))
  210.  
  211.     if core.hpoj_present:
  212.         log.error("Yes, HPOJ is running. HPLIP is not compatible with HPOJ. To run HPLIP, please remove HPOJ.")
  213.         num_errors += 1
  214.     else:
  215.         log.info("No, HPOJ is not running (OK).")
  216.  
  217.  
  218.     log.info()
  219.     log.info(log.bold("Checking Python version..."))
  220.     ver = sys.version_info
  221.     log.debug("sys.version_info = %s" % repr(ver))
  222.     ver_maj = ver[0]
  223.     ver_min = ver[1]
  224.     ver_pat = ver[2]
  225.  
  226.     if ver_maj == 2:
  227.         if ver_min >= 1:
  228.             log.info("OK, version %d.%d.%d installed" % ver[:3])
  229.         else:
  230.             log.error("Version %d.%d.%d installed. Please update to Python >= 2.1" % ver[:3])
  231.             sys.exit(1)
  232.  
  233.  
  234.     log.info()
  235.     log.info(log.bold("Checking PyQt version..."))
  236.  
  237.     # PyQt
  238.     try:
  239.         import qt
  240.     except ImportError:
  241.         num_errors += 1
  242.         log.error("NOT FOUND OR FAILED TO LOAD!")
  243.     else:
  244.         # check version of Qt
  245.         qtMajor = int(qt.qVersion().split('.')[0])
  246.  
  247.         if qtMajor < MINIMUM_QT_MAJOR_VER:
  248.             log.error("Incorrect version of Qt installed. Ver. 3.0.0 or greater required.")
  249.         else:
  250.             #check version of PyQt
  251.             try:
  252.                 pyqtVersion = qt.PYQT_VERSION_STR
  253.             except AttributeError:
  254.                 pyqtVersion = qt.PYQT_VERSION
  255.  
  256.             while pyqtVersion.count('.') < 2:
  257.                 pyqtVersion += '.0'
  258.  
  259.             (maj_ver, min_ver, pat_ver) = pyqtVersion.split('.')
  260.  
  261.             if pyqtVersion.find('snapshot') >= 0:
  262.                 log.error("A non-stable snapshot version of PyQt is installed (%s)." % pyqtVersion)
  263.                 num_errors += 1
  264.             else:
  265.                 try:
  266.                     maj_ver = int(maj_ver)
  267.                     min_ver = int(min_ver)
  268.                     pat_ver = int(pat_ver)
  269.                 except ValueError:
  270.                     maj_ver, min_ver, pat_ver = 0, 0, 0
  271.  
  272.                 if maj_ver < MINIMUM_PYQT_MAJOR_VER or \
  273.                     (maj_ver == MINIMUM_PYQT_MAJOR_VER and min_ver < MINIMUM_PYQT_MINOR_VER):
  274.                     num_errors += 1
  275.                     log.error("HPLIP may not function properly with the version of PyQt that is installed (%d.%d.%d)." % (maj_ver, min_ver, pat_ver))
  276.                     log.error("Ver. %d.%d or greater required." % (MINIMUM_PYQT_MAJOR_VER, MINIMUM_PYQT_MINOR_VER))
  277.                 else:
  278.                     log.info("OK, version %d.%d installed." % (maj_ver, min_ver))
  279.  
  280.  
  281.     log.info()
  282.     log.info(log.bold("Checking SIP version..."))
  283.  
  284.     sip_ver = None
  285.     try:
  286.         import pyqtconfig
  287.     except ImportError:
  288.         pass
  289.     else:
  290.         sip_ver = pyqtconfig.Configuration().sip_version_str 
  291.  
  292.     if sip_ver is not None:
  293.         log.info("OK, Version %s installed" % sip_ver)
  294.     else:
  295.         num_errors += 1
  296.         log.error("SIP not installed or version not found.")
  297.  
  298.     log.info()
  299.     log.info(log.bold("Checking for CUPS..."))
  300.     cups_ok = True
  301.  
  302.     status, output = utils.run('lpstat -r')
  303.     if status == 0:
  304.         log.info("Status: %s" % output.strip())
  305.     else:
  306.         log.error("Status: (Not available. CUPS may not be installed or not running.)")
  307.         cups_ok = False
  308.         num_errors += 1
  309.  
  310.     if cups_ok:
  311.         status, output = utils.run('cups-config --version')
  312.         if status == 0:
  313.             log.info("Version: %s" % output.strip())
  314.         else:
  315.             log.error("Version: (Not available. CUPS may not be installed or not running.)")
  316.             cups_ok = False
  317.             num_errors += 1
  318.         
  319.     if cups_ok:
  320.         cups_conf = '/etc/cups/cupsd.conf'
  321.         
  322.         try:
  323.             f = file(cups_conf, 'r')
  324.         except (IOError, OSError):
  325.             log.warn("%s file not found or not accessible." % cups_conf)
  326.         else:
  327.             for l in f:
  328.                 m = pat_cups_error_log.match(l)
  329.                 if m is not None:
  330.                     level = m.group(1).lower()
  331.                     log.info("error_log is set to level: %s" % level)
  332.                     
  333.                     if level not in ('debug', 'debug2'):
  334.                         log.note("For troubleshooting printing issues, it is best to have the CUPS 'LogLevel'")
  335.                         log.note("set to 'debug'. To set the LogLevel to debug, edit the file %s (as root)," % cups_conf)
  336.                         log.note("and change the line near the top of the file that begins with 'LogLevel' to read:")
  337.                         log.note("LogLevel debug")
  338.                         log.note("Save the file and then restart CUPS (see your OS/distro docs on how to restart CUPS).")
  339.                         log.note("Now, when you print, helpful debug information will be saved to the file:")
  340.                         log.note("/var/log/cups/error_log")
  341.                         log.note("You can monitor this file by running this command in a console/shell:")
  342.                         log.note("tail -f /var/log/cups/error_log")
  343.                     
  344.                     break
  345.                     
  346.  
  347.     log.info()
  348.  
  349.     log.info(log.bold("Checking for dbus/python-dbus..."))
  350.     
  351.     if dcheck.check_ps(['dbus-daemon']):
  352.         log.info("dbus daemon is running.")
  353.     else:
  354.         log.warn("dbus daemon is not running.")
  355.         
  356.     try:
  357.         import dbus
  358.         try:
  359.             log.info("python-dbus version: %s" % dbus.__version__)
  360.         except AttributeError:
  361.             try:
  362.                 log.info("python-dbus version: %s" % '.'.join([str(x) for x in dbus.version]))
  363.             except AttributeError:
  364.                 log.warn("python-dbus imported OK, but unknown version.")
  365.     except ImportError:
  366.         log.warn("python-dbus not installed.")
  367.     
  368.     log.info()
  369.     
  370.  
  371.     if time_flag == DEPENDENCY_RUN_AND_COMPILE_TIME:
  372.         tui.header("COMPILE AND RUNTIME DEPENDENCIES")
  373.         log.note("To check for compile-time only dependencies, re-run hp-check with the -c parameter (ie, hp-check -c).")
  374.         log.note("To check for run-time only dependencies, re-run hp-check with the -r parameter (ie, hp-check -r).")
  375.     
  376.     elif time_flag == DEPENDENCY_COMPILE_TIME:
  377.         tui.header("COMPILE TIME DEPENDENCIES")
  378.     
  379.     elif time_flag == DEPENDENCY_RUN_TIME:
  380.         tui.header("RUNTIME DEPENDENCIES")
  381.  
  382.     log.info()
  383.  
  384.     dd = core.dependencies.keys()
  385.     dd.sort()
  386.     for d in dd:
  387.         log.debug("***")
  388.  
  389.         if time_flag == DEPENDENCY_RUN_AND_COMPILE_TIME or time_flag == core.dependencies[d][4]:
  390.                 
  391.             log.info(log.bold("Checking for dependency: %s..." % core.dependencies[d][2]))
  392.  
  393.             if core.have_dependencies[d]:
  394.                 log.info("OK, found.")
  395.             else:
  396.                 num_errors += 1
  397.  
  398.                 if core.dependencies[d][4] == DEPENDENCY_RUN_AND_COMPILE_TIME:
  399.                     s = ''
  400.                 elif core.dependencies[d][4] == DEPENDENCY_COMPILE_TIME:
  401.                     s = '/COMPILE TIME ONLY'
  402.                     
  403.                 elif core.dependencies[d][4] == DEPENDENCY_RUN_TIME:
  404.                     s = '/RUNTIME ONLY'
  405.                 
  406.                 if core.dependencies[d][0]:
  407.                     log.error("NOT FOUND! This is a REQUIRED%s dependency. Please make sure that this dependency is installed before installing or running HPLIP." % s)
  408.                 else:
  409.                     log.warn("NOT FOUND! This is an OPTIONAL%s dependency. Some HPLIP functionality may not function properly." %s)
  410.  
  411.                 if core.distro_supported():
  412.                     packages_to_install, commands = core.get_dependency_data(d)
  413.  
  414.                     commands_to_run = []
  415.  
  416.                     if packages_to_install:
  417.                         package_mgr_cmd = core.get_distro_data('package_mgr_cmd')
  418.  
  419.                         if package_mgr_cmd:
  420.                             packages_to_install = ' '.join(packages_to_install)
  421.                             commands_to_run.append(utils.cat(package_mgr_cmd))
  422.  
  423.                     if commands:
  424.                         commands_to_run.extend(commands)
  425.  
  426.                     overall_commands_to_run.extend(commands_to_run)
  427.  
  428.                     if len(commands_to_run) == 1:
  429.                         log.info("To install this dependency, execute this command:")
  430.                         log.info(commands_to_run[0])
  431.  
  432.                     elif len(commands_to_run) > 1:
  433.                         log.info("To install this dependency, execute these commands:")
  434.                         for c in commands_to_run:
  435.                             log.info(c)
  436.  
  437.  
  438.             log.info()
  439.     
  440.     if time_flag in (DEPENDENCY_RUN_TIME, DEPENDENCY_RUN_AND_COMPILE_TIME):
  441.         tui.header("HPLIP INSTALLATION")
  442.  
  443.         scanning_enabled = utils.to_bool(sys_cfg.configure.get("scanner-build", False))
  444.  
  445.         log.info()
  446.         log.info(log.bold("Currently installed HPLIP version..."))
  447.         v = sys_cfg.hplip.version
  448.         home = sys_cfg.dirs.home
  449.  
  450.         if v:
  451.             log.info("HPLIP %s currently installed in '%s'." % (v, home))
  452.  
  453.             log.info()
  454.             log.info(log.bold("Current contents of '/etc/hp/hplip.conf' file:"))
  455.             output = file('/etc/hp/hplip.conf', 'r').read()
  456.             log.info(output)
  457.  
  458.         else:
  459.             log.info("Not found.")  
  460.  
  461.         
  462.         if device_avail:
  463.             if prop.par_build:
  464.                 tui.header("DISCOVERED PARALLEL DEVICES")
  465.                 
  466.                 devices = device.probeDevices(['par'])
  467.                 
  468.                 if devices:
  469.                     f = tui.Formatter()
  470.                     f.header = ("Device URI", "Model")
  471.                     
  472.                     for d, dd in devices.items():
  473.                         f.add((d, dd[0]))
  474.  
  475.                     f.output()
  476.                 
  477.                 else:
  478.                     log.info("No devices found.")
  479.                     
  480.                     if not core.have_dependencies['ppdev']:
  481.                         log.error("'ppdev' kernel module not loaded.")
  482.             
  483.             if prop.usb_build:
  484.                 tui.header("DISCOVERED USB DEVICES")                
  485.                 
  486.                 devices = device.probeDevices(['usb'])
  487.                 
  488.                 if devices:
  489.                     f = tui.Formatter()
  490.                     f.header = ("Device URI", "Model")
  491.                     
  492.                     for d, dd in devices.items():
  493.                         f.add((d, dd[0]))
  494.  
  495.                     f.output()
  496.                     
  497.                 else:
  498.                     log.info("No devices found.")
  499.         
  500.         
  501.         tui.header("INSTALLED CUPS PRINTER QUEUES")
  502.  
  503.         lpstat_pat = re.compile(r"""^device for (.*): (.*)""", re.IGNORECASE)
  504.  
  505.         status, output = utils.run('lpstat -v')
  506.         log.info()
  507.  
  508.         cups_printers = []
  509.         for p in output.splitlines():
  510.             try:
  511.                 match = lpstat_pat.search(p)
  512.                 printer_name = match.group(1)
  513.                 device_uri = match.group(2)
  514.                 cups_printers.append((printer_name, device_uri))
  515.             except AttributeError:
  516.                 pass
  517.  
  518.         log.debug(cups_printers)
  519.  
  520.         if cups_printers:
  521.             non_hp = False
  522.             for p in cups_printers:
  523.                 printer_name, device_uri = p
  524.                 try:
  525.                     back_end, is_hp, bus, model, serial, dev_file, host, port = \
  526.                         parseDeviceURI(device_uri)
  527.                 except Error:
  528.                     back_end, is_hp, bus, model, serial, dev_file, host, port = \
  529.                         '', False, '', '', '', '', '', 1
  530.  
  531.                 log.info(log.bold(printer_name))
  532.                 log.info(log.bold('-'*len(printer_name)))
  533.  
  534.                 x = "Unknown"
  535.                 if back_end == 'hpfax':
  536.                     x = "Fax"
  537.                 elif back_end == 'hp':
  538.                     x = "Printer"
  539.  
  540.                 log.info("Type: %s" % x)
  541.  
  542.                 if is_hp:
  543.                     x = 'Yes, using the %s: CUPS backend.' % back_end
  544.                 else:
  545.                     x = 'No, not using the hp: or hpfax: CUPS backend.'
  546.                     non_hp = True
  547.  
  548.                 log.info("Installed in HPLIP?: %s" % x)
  549.                 log.info("Device URI: %s" % device_uri)
  550.  
  551.                 ppd = os.path.join('/etc/cups/ppd', printer_name + '.ppd')
  552.  
  553.                 if os.path.exists(ppd):
  554.                     log.info("PPD: %s" % ppd)
  555.                     nickname_pat = re.compile(r'''\*NickName:\s*\"(.*)"''', re.MULTILINE)
  556.  
  557.                     f = file(ppd, 'r').read(4096)
  558.  
  559.                     try:
  560.                         desc = nickname_pat.search(f).group(1)
  561.                     except AttributeError:
  562.                         desc = ''
  563.  
  564.                     log.info("PPD Description: %s" % desc)
  565.  
  566.                     status, output = utils.run('lpstat -p%s' % printer_name)
  567.                     log.info("Printer status: %s" % output.replace("\n", ""))
  568.  
  569.                     if back_end == 'hpfax' and desc != 'HP Fax':
  570.                         num_errors += 1
  571.                         log.error("Incorrect PPD file for fax queue '%s'. Fax queues must use 'HP-Fax-hplip.ppd'." % printer_name)
  572.  
  573.                     elif back_end == 'hp' and desc == 'HP Fax':
  574.                         num_errors += 1
  575.                         log.error("Incorrect PPD file for a print queue '%s'. Print queues must not use 'HP-Fax-hplip.ppd'." % printer_name)
  576.  
  577.                     elif back_end not in ('hp', 'hpfax'):
  578.                         log.warn("Printer is not HPLIP installed. Printers must use the hp: or hpfax: CUPS backend to function in HPLIP.")
  579.                         num_errors += 1
  580.  
  581.                 if device_avail and is_hp:
  582.                     d = None
  583.                     try:
  584.                         try:
  585.                             d = device.Device(device_uri)
  586.                         except Error:
  587.                             log.error("Device initialization failed.")
  588.                             continue
  589.  
  590.                         plugin = d.mq.get('plugin', PLUGIN_NONE)
  591.                         if plugin in (PLUGIN_REQUIRED, PLUGIN_OPTIONAL):
  592.                             home = sys_cfg.dirs.home or os.path.realpath(os.path.normpath(os.getcwd()))
  593.                             
  594.                             log.debug("home=%s" % home)
  595.  
  596.                             model = model.lower()
  597.  
  598.                             if os.path.exists(os.path.join(home, "data", "plugins", "%s.plugin" % model)):
  599.                                 if plugin == PLUGIN_REQUIRED:
  600.                                     log.info("Required plug-in status: Installed")
  601.                                 else:
  602.                                     log.info("Optional plug-in status: Installed")
  603.                             else:
  604.                                 num_errors += 1
  605.                                 
  606.                                 if plugin == PLUGIN_REQUIRED:
  607.                                     log.error("Required plug-in status: Not installed")
  608.                                 else:
  609.                                     log.warn("Optional plug-in status: Not installed") 
  610.                                 
  611.  
  612.                         if bus in ('par', 'usb'):
  613.                             try:
  614.                                 d.open()
  615.                             except Error, e:
  616.                                 log.error(e.msg)
  617.                                 deviceid = ''
  618.                             else:
  619.                                 deviceid = d.getDeviceID()
  620.                                 log.debug(deviceid)
  621.  
  622.                             if not deviceid:
  623.                                 #log.error("Communication status: Failed")
  624.                                 num_errors += 1
  625.                             else:
  626.                                 log.info("Communication status: Good")
  627.  
  628.                         elif bus == 'net':
  629.                             try:
  630.                                 error_code, deviceid = d.getPML(pml.OID_DEVICE_ID)
  631.                             except Error:
  632.                                 #log.error("Communication with device failed.")
  633.                                 error_code = pml.ERROR_COMMAND_EXECUTION
  634.                             
  635.                             if error_code > pml.ERROR_MAX_OK:
  636.                                 #log.error("Communication status: Failed")
  637.                                 num_errors += 1
  638.                             else:
  639.                                 log.info("Communication status: Good")
  640.  
  641.                     finally:
  642.                         if d is not None:
  643.                             d.close()
  644.  
  645.                     log.info()
  646.  
  647.  
  648.  
  649.         else:
  650.             log.warn("No queues found.")
  651.  
  652.         if scanning_enabled:
  653.             tui.header("SANE CONFIGURATION")
  654.             log.info(log.bold("'hpaio' in '/etc/sane.d/dll.conf'..."))
  655.             try:
  656.                 f = file('/etc/sane.d/dll.conf', 'r')
  657.             except IOError:
  658.                 log.error("'/etc/sane.d/dll.conf' not found. Is SANE installed?")
  659.                 num_errors += 1
  660.             else:
  661.                 found = False
  662.                 for line in f:
  663.                     if 'hpaio' in line:
  664.                         found = True
  665.  
  666.                 if found:
  667.                     log.info("OK, found. SANE backend 'hpaio' is properly set up.")
  668.                 else:
  669.                     num_errors += 1
  670.                     log.error("Not found. SANE backend 'hpaio' NOT properly setup (needs to be added to /etc/sane.d/dll.conf).")
  671.  
  672.                 log.info()
  673.                 log.info(log.bold("Checking output of 'scanimage -L'..."))
  674.                 if utils.which('scanimage'):
  675.                     status, output = utils.run("scanimage -L")
  676.                     log.info(output)
  677.                 else:
  678.                     log.error("scanimage not found.")
  679.  
  680.         tui.header("PYTHON EXTENSIONS")
  681.  
  682.         log.info(log.bold("Checking 'cupsext' CUPS extension..."))
  683.         try:
  684.             import cupsext
  685.         except ImportError:
  686.             num_errors += 1
  687.             log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of cupsext.")
  688.         else:
  689.             log.info("OK, found.")
  690.  
  691.         log.info()
  692.         log.info(log.bold("Checking 'pcardext' Photocard extension..."))
  693.         try:
  694.             import pcardext
  695.         except ImportError:
  696.             num_errors += 1
  697.             log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of pcardext.")
  698.         else:
  699.             log.info("OK, found.")
  700.  
  701.         log.info()
  702.         log.info(log.bold("Checking 'hpmudext' I/O extension..."))
  703.         try:
  704.             import hpmudext
  705.             hpmudext_avail = True
  706.         except ImportError:
  707.             hpmudext_avail = False
  708.             num_errors += 1
  709.             log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of hpmudext.")
  710.         else:
  711.             log.info("OK, found.")        
  712.  
  713.         if scanning_enabled:
  714.             log.info()
  715.             log.info(log.bold("Checking 'scanext' SANE scanning extension..."))
  716.             try:
  717.                 import scanext
  718.             except ImportError:
  719.                 num_errors += 1
  720.                 log.error("NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of scanext.")
  721.             else:
  722.                 log.info("OK, found.")        
  723.  
  724.                 log.info()
  725.  
  726.         tui.header("USB I/O SETUP")
  727.  
  728.         if hpmudext_avail:
  729.             lsusb = utils.which('lsusb')
  730.             if lsusb:
  731.                 log.info()
  732.                 log.info(log.bold("Checking for permissions of USB attached printers..."))
  733.                 lsusb = os.path.join(lsusb, 'lsusb')
  734.                 status, output = utils.run("%s -d03f0:" % lsusb)
  735.  
  736.                 lsusb_pat = re.compile("""^Bus\s([0-9a-fA-F]{3,3})\sDevice\s([0-9a-fA-F]{3,3}):\sID\s([0-9a-fA-F]{4,4}):([0-9a-fA-F]{4,4})(.*)""", re.IGNORECASE)
  737.                 log.debug(output)
  738.  
  739.                 for o in output.splitlines():
  740.                     ok = True
  741.                     match = lsusb_pat.search(o)
  742.  
  743.                     if match is not None:
  744.                         bus, device, vid, pid, mfg = match.groups()
  745.                         log.info("\nHP Device 0x%x at %s:%s: " % (int(pid, 16), bus, device))
  746.                         result_code, deviceuri = hpmudext.make_usb_uri(bus, device)
  747.  
  748.                         if result_code == hpmudext.HPMUD_R_OK:
  749.                             log.info("    Device URI: %s" %  deviceuri)
  750.                         else:
  751.                             log.warn("    Device URI: (Makeuri FAILED)")
  752.  
  753.                         devnode = os.path.join("/", "dev", "bus", "usb", bus, device)
  754.  
  755.                         if not os.path.exists(devnode):
  756.                             devnode = os.path.join("/", "proc", "bus", "usb", bus, device)
  757.  
  758.                         if os.path.exists(devnode):
  759.                             log.info("    Device node: %s" % devnode)
  760.  
  761.                             st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid, \
  762.                                 st_size, st_atime, st_mtime, st_ctime = \
  763.                                 os.stat(devnode)
  764.  
  765.                             log.info("    Mode: 0%o" % (st_mode & 0777))
  766.  
  767.                             getfacl = utils.which('getfacl')
  768.                             if getfacl:
  769.                                 getfacl = os.path.join(getfacl, "getfacl")
  770.  
  771.                                 status, output = utils.run("%s %s" % (getfacl, devnode))
  772.  
  773.                                 log.info(output)
  774.  
  775.  
  776.     tui.header("SUMMARY")
  777.  
  778.     if num_errors:
  779.         if num_errors == 1:
  780.             log.error("1 error or warning.")
  781.         else:
  782.             log.error("%d errors and/or warnings." % num_errors)
  783.  
  784.         if overall_commands_to_run:
  785.             log.info()
  786.             log.info(log.bold("Summary of needed commands to run to satisfy missing dependencies:"))
  787.             for c in overall_commands_to_run:
  788.                 log.info(c)
  789.  
  790.         log.info()
  791.         log.info("Please refer to the installation instructions at:")
  792.         log.info("http://hplip.sourceforge.net/install/index.html\n")
  793.  
  794.     else:
  795.         log.info(log.green("No errors or warnings."))
  796.  
  797. except KeyboardInterrupt:
  798.     log.error("User exit")
  799.     
  800. log.info()
  801. log.info("Done.")
  802.  
  803.